﻿using Coolzon.Common;
using Coolzon.UI.Core.Runtime.Script;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using RT = Coolzon.Metadata.Runtime;

namespace Coolzon.UI.Core
{
    public partial class Widget
    {
        public static string OnMouseLeftDownEvent = "OnMouseLeftDown";

        /// <summary>
        /// 调用脚本引擎执行脚本事件
        /// </summary>
        /// <param name="scriptEngine"></param>
        /// <param name="eventSource"></param>
        /// <param name="args"></param>
        public bool InvokeScriptEvent(ScriptEngine scriptEngine, string eventSource, params object[] args)
        {
            if (this.Metadata == null || this.Metadata.ScriptEvents == null || this.Metadata.ScriptEvents.Count <= 0)
            {
                return false;
            }

            for (int index = 0; index < this.Metadata.ScriptEvents.Count; index++)
            {
                RT.ScriptEvent scriptEvent = this.Metadata.ScriptEvents[index];
                if (string.Equals(scriptEvent.Source, eventSource))
                {
                    this.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        try
                        {
                            scriptEngine.Run(scriptEvent.Script, args);
                        }
                        catch (Exception ex)
                        {
                            Logger.ErrorToTag("Script", string.Format("组件:{0},执行脚本事件:{1},出错：{2}", this.Name, eventSource, ex));
                        }
                    }), null);
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 检查是否含有此事件的脚本绑定
        /// </summary>
        /// <param name="eventSource"></param>
        /// <returns></returns>
        protected bool HasScriptEvent(string eventSource)
        {
            if (this.Metadata.ScriptEvents == null)
            {
                return false;
            }

            for (int index = 0; index < this.Metadata.ScriptEvents.Count; index++)
            {
                RT.ScriptEvent scriptEvent = this.Metadata.ScriptEvents[index];
                if (string.Equals(scriptEvent.Source, eventSource))
                {
                    return true;
                }
            }
            return false;
        }

        ///// <summary>
        ///// 触发事件
        ///// </summary>
        ///// <param name="eventType">鼠标事件类型</param>
        ///// <param name="point">触发事件的坐标(相对于此组件的坐标)</param>
        //[Obsolete("不使用")]
        //public void RaiseMouseEvent(MouseEventType eventType, Point point)
        //{
        //    if (eventType.Name == MouseEventType.MouseLeftDown.Name)
        //    {
        //        if (HasScriptEvent(OnMouseLeftDownEvent))
        //        {
        //            this.InvokeScriptEvent(PartContext.ScriptEngine,
        //                OnMouseLeftDownEvent,
        //                this.GetScriptObj(),
        //                "");
        //        }
        //        //else if (HasScriptEvent("OnMouseRightDown"))
        //        //{
        //        //    this.InvokeScriptEvent(this.PartContext.ScriptEngine,
        //        //        "OnMouseRightDown",
        //        //        this.GetScriptObj(),
        //        //        "");
        //        //}
        //    }

           // OnReceiveMouseEvent(eventType, point);

            //if (this.EventList != null)
            //{
            //    // 扫描组件的所有事件配置
            //    for (int index = 0; index < this.EventList.Count; index++)
            //    {
            //        Metadata.Event @event = this.EventList[index];
            //        // 检查事件类型
            //        if (@event.Source.ToUpper() == eventType.Name.ToUpper())
            //        {
            //            Common.EventBus.Instance.Publish(new Event.PartMouseEvent(this.Name, eventType.Name, point.X, point.Y));
            //        }
            //    }
            //}
        //}

        //[Obsolete("不使用")]
        //protected virtual bool OnReceiveMouseEvent(MouseEventType eventType, Point point)
        //{
        //    return true;
        //}

        #region part event

        ///// <summary>
        ///// 发送组件的交互事件
        ///// </summary>
        ///// <param name="clientID">终端编号</typeparam>
        ///// <param name="eventName">事件名称</typeparam>
        ///// <typeparam name="T">事件对象，事件对象需要支持序列化</typeparam>
        ///// <param name="eventData"></param>
        //protected void SendPartEvent<T>(string clientID, string eventName, T eventData)
        //{
        //    CorePartEvent @event = new Coolzon.Event.Core.CorePartEvent();
        //    @event.PartName = this.Name;
        //    @event.ClientID = clientID;
        //    @event.EventName = eventName;
        //    @event.Data = Coolzon.Common.SerializeUtility.SerializeToBinary(eventData);

        //    Coolzon.Event.Core.CoreEventBus.PublishAsync(@event);
        //}

        /// <summary>
        /// 接收到组件事件
        /// </summary>
        /// <param name="clientID">终端编号</typeparam>
        /// <param name="eventName">事件名称</typeparam>
        /// <param name="eventData">事件对象数据，序列化事件对象</param>
        public void ReceivePartEvent(string clientID, string eventName, byte[] eventData)
        {
            this.Dispatcher.Invoke(() =>
            {
                OnReceivePartEvent(clientID, eventName, eventData);
            });
        }

        /// <summary>
        /// 接收到组件事件
        /// </summary>
        /// <param name="clientID">终端编号</typeparam>
        /// <param name="eventName">事件名称</typeparam>
        /// <param name="eventData">事件对象数据，序列化事件对象</param>
        protected virtual void OnReceivePartEvent(string clientID, string eventName, byte[] eventData)
        {
        }

        #endregion
    }
}
